package com.ai.dmc.index.quartz.service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.ai.dmc.index.base.impl.base.BaseServiceImpl;
import com.ai.dmc.index.common.data.PubConstant;
import com.ai.dmc.index.common.exception.BusinessException;
import com.ai.dmc.index.intf.service.quartz.IIndexRefreshTimeService;
import com.ai.dmc.utils.string.StringUtil;

/**
 * Title：指标状态定时刷新
 * Description： 指标状态定时刷新
 * Copyright：Copyright (c) 2009
 * Company：北京亚信智慧数据科技有限公司
 * @author lg, 2016年3月16日
 * @version 1.0
 */
public class IndexRefreshTimeServiceImpl extends BaseServiceImpl implements IIndexRefreshTimeService {
    // 定义对应Mapper文件的命名空间
    private static final String NAMESPACE = "IIndexRefreshTimeDao.";

    /*
     * 指标状态定时刷新
     */
    public void indexStateRefresh() throws BusinessException {
    	
    	System.out.println("=========================================================");
//        Map<String, String> pram = new HashMap<String, String>();
//        // 指标正常状态
//        pram.put("normalCode", PubConstant.INDEX_STATE_NORMAL);
//        // 查询状态正常的基本指标
//        List<Map<String, String>> resultBaseIndexList = this.getBaseDao().queryForList(
//                NAMESPACE + "queryAllValidBaseIndex", pram);
//        Date nowTime = new Date();// 当前时间
//        for (Map<String, String> baseIndexMap : resultBaseIndexList) {
//            String baseIndexId = String.valueOf(baseIndexMap.get("baseIdxId"));
//            if (StringUtil.isEmpty(baseIndexId)) {
//                continue;
//            }
//            // 查询此基本指标下的指标信息
//            Map<String, String> pa = new HashMap<String, String>();
//            // 指标正常状态
//            pa.put("normalCode", PubConstant.INDEX_STATE_NORMAL);
//            // 指标生命周期规则 生效状态
//            pa.put("ruleCfgStateCode", PubConstant.INDEX_RULE_CFG_STA_NORMAL);
//            // 指标基本ID
//            pa.put("baseIndexId", baseIndexId);
//            // 查询状态正常的指标
//            List<Map<String, String>> resultIndexList = this.getBaseDao().queryForList(
//                    NAMESPACE + "queryAllValidIndexByBaseIndexId", pa);
//            for (Map<String, String> iMap : resultIndexList) {
//                if (iMap.get("idxId") == null || iMap.get("idxId").equals("") || iMap.get("statisCycleCode") == null
//                        || iMap.get("statisCycleCode").equals("") || iMap.get("expireTime") == null
//                        || iMap.get("expireTime").equals("") || iMap.get("versionCode") == null
//                        || iMap.get("versionCode").equals("")) {
//                    continue;
//                }
//                String idxId = iMap.get("idxId");
//                String expireStr = iMap.get("expireTime");
//                String cycleCode = iMap.get("statisCycleCode");
//                String versionCode = iMap.get("versionCode");
//                String stateCode = iMap.get("idxStateCode");
//                if ((iMap.get("clickNum") != null && !(iMap.get("clickNum").equals("")))
//                        && (iMap.get("countClickCycle") != null && !(iMap.get("countClickCycle").equals("")))
//                        && (iMap.get("refreshRate") != null && !(iMap.get("refreshRate").equals("")))
//                        && (iMap.get("countRefreshCycle") != null && !(iMap.get("countRefreshCycle").equals("")))
//                        && (iMap.get("invalidBefNum") != null && !(iMap.get("invalidBefNum").equals("")))
//                        && (iMap.get("baseNum") != null && !(iMap.get("baseNum").equals("")))) {
//                    try {
//                     // 根据条件 设置指标 即将失效
//                        changeIndexState(idxId, versionCode, cycleCode, expireStr, nowTime, stateCode,
//                                Integer.parseInt(iMap.get("countClickCycle")), Integer.parseInt(iMap.get("clickNum")),
//                                Integer.parseInt(iMap.get("countRefreshCycle")),
//                                Double.parseDouble(iMap.get("refreshRate")), Integer.parseInt(iMap.get("invalidBefNum")),
//                                Integer.parseInt(iMap.get("baseNum")));
//                    } catch (Exception e) {
//                        e.printStackTrace();
//                    }
//                    
//                }
//                // 判断此基本指标是否失效
//                List<Map<String, String>> indexList = this.getBaseDao().queryForList(
//                        NAMESPACE + "queryIndexByBaseIndexId", pa);
//                if (null == indexList || indexList.size() <= 0) {
//                    Map<String, String> paraMap = new HashMap<String, String>();
//                    paraMap.put("stateCode", String.valueOf(PubConstant.INDEX_STA_SOONINVALID));
//                    paraMap.put("baseIdxId", baseIndexId);
//                    updateIndiState(paraMap);
//                }
//            }
//        }
    }

    /*
     * 根据时间、点击数、刷新成功率 改变指标状态
     */
    private void changeIndexState(String idxId, String versionCode, String cycleCode, String expireStr, Date nowTime,
            String stateCode, int invalidCountMon, int invalidCount, int invalidCycleNum, Double invalidCycleRate,
            int invalidDays, int baseDays) {
        String sqlMapId = "updateIndexStateByIndexId";
        Map<String, String> pram = new HashMap<String, String>();
        pram.put("idxId", idxId);
        pram.put("versionCode", versionCode);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        pram.put("nowTime", sdf.format(nowTime));
        // 当前时间距失效时间 天数
        Double diffDays = getDiffDay(expireStr, nowTime);
        if (diffDays <= invalidDays) {
            // 失效期已到、设置指标状态 即将失效
            pram.put("stateCode", String.valueOf(PubConstant.INDEX_STA_SOONINVALID));
            this.getBaseDao().update(sqlMapId, pram);
        } else {
            // 正常状态 的 指标
            if (stateCode.equals(String.valueOf(PubConstant.INDEX_STATE_NORMAL))) {
                // 指标连续周期内 访问数小于配置值或 刷新成功率小于设置值 则更新指标为待失效
                if (isLessThanCount(nowTime, invalidCountMon, idxId, versionCode, invalidCount, baseDays)
                        ||indexCycleRate(nowTime, idxId, versionCode, invalidCycleNum, String.valueOf(invalidCycleRate),
                        baseDays, cycleCode)) {
                    // 设置指标状态为 即将失效状态（待失效）
                    pram.put("stateCode", String.valueOf(PubConstant.INDEX_STA_SOONINVALID));
                    this.getBaseDao().update(sqlMapId, pram);
                }

            }
        }
    }

    /**
     * 判断 连续interCycTime个周期 周期内点击数<=N
     * 
     * @param
     * @throws ParseException
     */
    private boolean isLessThanCount(Date curDate, int interCycTime, String indexId, String versionCode,
            int invalidCount, int baseDays) {
        String staTime = "";
        String endTime = "";
        long visitNum = 0;
        boolean flag = true;
        for (int i = 1; i <= interCycTime; i++) {
            // 获得指标周期的起始时间、结束时间 ，指标周期为一星期、7日
             endTime = getTimeTypeYMDHMS(curDate, (interCycTime - i) * baseDays);
             staTime = getTimeTypeYMDHMS(curDate, (interCycTime - i + 1) * baseDays);
            visitNum = indexVisitCountBytime(indexId, versionCode, staTime, endTime);// 获取指标点击量
            if (visitNum > invalidCount) {// 点击次数大于配置的 点击次数 则不设置预失效
                flag = false;
                break;
            }
        }
        if (interCycTime <= 0) {
            flag = false;
        }
        return flag;
    }

    /**
     * 统计指标的点击量
     * 
     * @param versionCode
     *            参数未用到
     * @param staTime
     *            、endTime 格式为 "yyyy-MM-dd HH:mm:ss"
     */
    private long indexVisitCountBytime(String idxId, String versionCode, String staTime, String endTime) {
        long visitCount = 0;
        String sqlMapId = NAMESPACE + "getIndexVisitByTime";
        Map<String, String> pram = new HashMap<String, String>();
        pram.put("idxId", idxId);
        pram.put("versionCode", versionCode);
        pram.put("staTime", staTime);
        pram.put("endTime", endTime);
        // 返回点击量
        visitCount = this.getBaseDao().getTotalCount(sqlMapId, pram);
        return visitCount;
    }

    /**
     * 获取curDate 前interval天的日期
     * 
     * @param Date
     *            date, int interval
     * @return 返回格式 年月日 时分秒
     */
    private String getTimeTypeYMDHMS(Date curDate, int interval) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(curDate);
        cal.add(Calendar.DATE, -interval);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(cal.getTime());
    }

    /*
     * 判断 指标连续周期 不成功
     */
    private boolean indexCycleRate(Date curDate, String indexId, String versionCode, int cycleNum,
            String invalidCycleRate, int baseDays, String cycleCode) {
        boolean flag = true;
        String staTime = "";
        String endTime = "";
        double sucRate = 0;
        long visitSucNum = 0;
        long visitTolNum = 0;
        for (int i = 1; i <= cycleNum; i++) {
            // 获得指标每个周期的起始时间、结束时间
             endTime = getTimeTypeYMD(curDate, (cycleNum - i) * baseDays);
             staTime = getTimeTypeYMD(curDate, (cycleNum - i + 1) * baseDays);
            // 获取指标刷新成功数
            visitSucNum = indexCycleRateNumBytime(indexId, versionCode, staTime, endTime, true);
            // 获取指标刷新总数
            visitTolNum = indexCycleRateNumBytime(indexId, versionCode, staTime, endTime, false);
            if (visitTolNum > 0) {
                sucRate = ((double) visitSucNum) / visitTolNum;
                // 周期成功率大于预设的成功率 则指标不设置预失效
                if (sucRate > Double.parseDouble(invalidCycleRate)) {
                    flag = false;
                    break;
                }
            }
        }
        if (cycleNum <= 0) {
            flag = false;
        }
        return flag;
    }

    /**
     * 统计指标的刷新数
     */
    private long indexCycleRateNumBytime(String idxId, String versionCode, String staTime, String endTime,
            boolean isSuccess) {
        long visitCount = 0;
        String sqlMapId = NAMESPACE + "getIndexCycleRateCount";
        Map<String, String> pram = new HashMap<String, String>();
        if (isSuccess) {
            pram.put("resultFlag", "1");
        }
        pram.put("idxId", idxId);
        pram.put("versionCode", versionCode);
        pram.put("staTime", staTime);
        pram.put("endTime", endTime);
        // 返回点击量
        visitCount = this.getBaseDao().getTotalCount(sqlMapId, pram);
        return visitCount;
    }

    /**
     * 获取curDate 前interval天的日期
     * 
     * @param Date
     *            date, int interval
     * @return 返回格式 年月日
     */
    private String getTimeTypeYMD(Date curDate, int interval) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(curDate);
        cal.add(Calendar.DATE, -interval);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        return sdf.format(cal.getTime());
    }

    private void updateIndiState(Map<String, String> paraMap) throws BusinessException {
        // 更新基本信息表里的指标状态
        this.getBaseDao().update(NAMESPACE + "updateIndiBaseState", paraMap);
        // 更新信息表里的指标状态
        // this.getBaseDao().update(NAMESPACE + "updateIndiState", paraMap);
    }

    /**
     * expireDate与当前日期相差天数
     * 
     * @param date
     * @return days
     */
    private Double getDiffDay(String date, Date nowTime) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date d1 = null;
        try {
            d1 = sdf.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Date d2 = nowTime;
        Calendar cal = Calendar.getInstance();
        cal.setTime(d1);
        Double day1 = (double) cal.getTimeInMillis();
        cal.setTime(d2);
        Double day2 = (double) cal.getTimeInMillis();
        Double betweenDay = (day1 - day2) / (1000 * 3600 * 24);// 天数
        return betweenDay;
    }

}
